1   /*
2    * Copyright (C) 2010 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect;
18  
19  import static com.google.common.truth.Truth.assertThat;
20  
21  import com.google.common.annotations.GwtCompatible;
22  
23  import junit.framework.AssertionFailedError;
24  import junit.framework.TestCase;
25  
26  import java.util.Iterator;
27  import java.util.NoSuchElementException;
28  
29  /** Tests for {@link AbstractSequentialIterator}. */
30  @GwtCompatible(emulated = true)
31  public class AbstractSequentialIteratorTest extends TestCase {
32  
33    public void testDoubler() {
34      Iterable<Integer> doubled = new Iterable<Integer>() {
35        @Override
36        public Iterator<Integer> iterator() {
37          return newDoubler(2, 32);
38        }
39      };
40      assertThat(doubled).iteratesAs(2, 4, 8, 16, 32);
41    }
42  
43    public void testSampleCode() {
44      Iterable<Integer> actual = new Iterable<Integer>() {
45        @Override
46        public Iterator<Integer> iterator() {
47          Iterator<Integer> powersOfTwo = new AbstractSequentialIterator<Integer>(1) {
48            protected Integer computeNext(Integer previous) {
49              return (previous == 1 << 30) ? null : previous * 2;
50            }
51          };
52          return powersOfTwo;
53        }
54      };
55      assertThat(actual).iteratesAs(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
56          4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304,
57          8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824);
58    }
59  
60    public void testEmpty() {
61      Iterator<Object> empty = newEmpty();
62      assertFalse(empty.hasNext());
63      try {
64        empty.next();
65        fail();
66      } catch (NoSuchElementException expected) {
67      }
68      try {
69        empty.remove();
70        fail();
71      } catch (UnsupportedOperationException expected) {
72      }
73    }
74  
75    public void testBroken() {
76      Iterator<Object> broken = newBroken();
77      assertTrue(broken.hasNext());
78      // We can't retrieve even the known first element:
79      try {
80        broken.next();
81        fail();
82      } catch (MyException expected) {
83      }
84      try {
85        broken.next();
86        fail();
87      } catch (MyException expected) {
88      }
89    }
90  
91    private static Iterator<Integer> newDoubler(int first, final int last) {
92      return new AbstractSequentialIterator<Integer>(first) {
93        @Override
94        protected Integer computeNext(Integer previous) {
95          return (previous == last) ? null : previous * 2;
96        }
97      };
98    }
99  
100   private static <T> Iterator<T> newEmpty() {
101     return new AbstractSequentialIterator<T>(null) {
102       @Override
103       protected T computeNext(T previous) {
104         throw new AssertionFailedError();
105       }
106     };
107   }
108 
109   private static Iterator<Object> newBroken() {
110     return new AbstractSequentialIterator<Object>("UNUSED") {
111       @Override
112       protected Object computeNext(Object previous) {
113         throw new MyException();
114       }
115     };
116   }
117 
118   private static class MyException extends RuntimeException {}
119 }
120